﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace _05.TwoKeysDictionary
{
    public static class TestGenerator
    {
        public static Random random = new Random();
        const int maxLineNumber = 10000;
        const string separator = " | ";

        private static TwoKeysDictionary<string, int, string> studentsInDictionary;

        private static int[] iMeter = { 0, 846, 846, 850, 909, 945, 975, 1000, 1001 };

        private static Interval AddInterval = new Interval(iMeter[0], iMeter[1]);
        private static Interval ClearInterval = new Interval(iMeter[1], iMeter[2]);
        private static Interval CountInterval = new Interval(iMeter[2], iMeter[3]);

        private static Interval CreateInterval = new Interval(iMeter[3], iMeter[7]);

        private static Interval GetInterval = new Interval(iMeter[3], iMeter[4]);
        private static Interval ContaintInterval = new Interval(iMeter[4], iMeter[6]);
        private static Interval ContaintNotInterval = new Interval(iMeter[5], iMeter[6]);
        private static Interval RemoveInterval = new Interval(iMeter[6], iMeter[7]);

        private static Interval ForeachInterval = new Interval(iMeter[7], iMeter[8]);


        private static void PrintInput(string inputFileName)
        {
            StreamWriter writer = new StreamWriter(inputFileName);
            int lineNumber = 0;

            using (writer)
            {
                while (lineNumber < maxLineNumber)
                {
                    Student usedStudent = new Student();
                    int randomNext = random.Next(iMeter[0], iMeter[iMeter.Length - 1] + 1);

                    lineNumber = AddCommand(writer, lineNumber, usedStudent, randomNext);

                    lineNumber = ClearCommand(writer, lineNumber, randomNext);

                    lineNumber = CountCommand(writer, lineNumber, randomNext);

                    if (CreateInterval.IsInside(randomNext))
                    {
                        if (studentsInDictionary.Count > 0)
                        {
                            Tuple<string, int, string> getStudent = RandomValue(studentsInDictionary.ToArray());
                            usedStudent = new Student(getStudent);
                            lineNumber++;

                            if (GetInterval.IsInside(randomNext))
                            {
                                writer.WriteLine("Get{0}{1}{0}{2}", separator, usedStudent.Faculty, usedStudent.FN);
                            }
                            if (ContaintInterval.IsInside(randomNext))
                            {
                                if (ContaintNotInterval.IsInside(randomNext))
                                {
                                    usedStudent = new Student();
                                }
                                writer.WriteLine("ContainsKey{0}{1}{0}{2}", separator, usedStudent.Faculty, usedStudent.FN);
                            }
                            if (RemoveInterval.IsInside(randomNext))
                            {
                                studentsInDictionary.Remove(usedStudent.Faculty, usedStudent.FN);

                                writer.WriteLine("Remove{0}{1}{0}{2}", separator, usedStudent.Faculty, usedStudent.FN);
                            }
                        }
                    }
                    if (ForeachInterval.IsInside(randomNext))
                    {
                        writer.WriteLine("Foreach");
                        lineNumber++;
                    }
                }
                writer.WriteLine();
            }
        }

        private static int CountCommand(StreamWriter writer, int lineNumber, int randomNext)
        {
            if (CountInterval.IsInside(randomNext))
            {
                writer.WriteLine("Count");
                lineNumber++;
            }
            return lineNumber;
        }

        private static int ClearCommand(StreamWriter writer, int lineNumber, int randomNext)
        {
            if (ClearInterval.IsInside(randomNext))
            {
                studentsInDictionary.Clear();
                writer.WriteLine("Clear");
                lineNumber++;
            }
            return lineNumber;
        }

        private static int AddCommand(StreamWriter writer, int lineNumber, Student usedStudent, int randomNext)
        {
            if (AddInterval.IsInside(randomNext))
            {
                if (!studentsInDictionary.ContainsKeys(usedStudent.Faculty, usedStudent.FN))
                {
                    studentsInDictionary.Add(usedStudent.Faculty, usedStudent.FN, usedStudent.Name);
                    writer.WriteLine("Add{0}{1}{0}{2}{0}{3}", separator, usedStudent.Faculty, usedStudent.FN, usedStudent.Name);
                    lineNumber++;
                }
            }
            return lineNumber;
        }

        private static T RandomValue<T>(T[] inArray)
        {
            return inArray[random.Next() % inArray.Length];
        }

        public static void CreateTest(string inputFileName)
        {
            studentsInDictionary = new TwoKeysDictionary<string, int, string>();

            PrintInput(@"..\..\Tests\" + inputFileName);
        }
    }
}
